package com.mcptt.http.auth.process.result.info;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.mcptt.http.tool.EncryptionTool;

import android.text.TextUtils;
import android.util.Base64;

public class AuthorizationInfo
{
	public final static String DefauleValue = "";

	private String authType = null;
	private String username = null;
	private String realm = null;
	private String nonce = null;
	private String uri = null;
	private String response = null;
	private String qop = null;
	private String nc = null;
	private String cnonce = null;
	private String opaque = null;

	private Map<String, String> valueMap = null;

	public AuthorizationInfo(String authStr)
	{
		this.parse(authStr);
		this.realm = this.getValue("realm");
		this.qop = this.getValue("qop");
		this.nonce = this.getValue("nonce");
		this.opaque = this.getValue("opaque");
	}

	public boolean checkReturnParamOk()
	{
		if(realm == null
				|| realm.length() <= 0)
		{
			return false;
		}
		if(qop == null
				|| qop.length() <= 0)
		{
			return false;
		}
		if(nonce == null
				|| nonce.length() <= 0)
		{
			return false;
		}
		if(opaque == null
				|| opaque.length() <= 0)
		{
			return false;
		}
		return true;
	}

	public String toString()
	{
		StringBuffer strBuf = new StringBuffer("AuthorizationInfo ");
		strBuf.append("authType=").append(authType).append(",");
		strBuf.append("username=\"").append(username).append("\",");
		strBuf.append("realm=\"").append(realm).append("\",");
		strBuf.append("nonce=\"").append(nonce).append("\",");
		strBuf.append("uri=\"").append(uri).append("\",");
		strBuf.append("response=\"").append(response).append("\",");
		strBuf.append("qop=").append(qop).append(",");
		strBuf.append("nc=").append(nc).append(",");
		strBuf.append("cnonce=\"").append(cnonce).append("\",");
		strBuf.append("opaque=\"").append(opaque).append("\",");
		strBuf.append("valueMap=").append(valueMap).append(";");

		return strBuf.toString();
	}

	public void generateDigestAuth(String username, String password,String uri)
	{
		this.username = username;
		this.cnonce = generateCNonce(18);
		this.nc = "00000001";
		this.uri = uri;
		String value = concatWithSeparator(":", username,realm, password);
		String ha1 = EncryptionTool.getMD5(value);
		value = concatWithSeparator(":","GET", uri);
		String ha2 = EncryptionTool.getMD5(value);
		if (!TextUtils.isEmpty(ha1) && !TextUtils.isEmpty(ha2))
		{
			value = concatWithSeparator(":", ha1,nonce, nc, cnonce, qop, ha2);
			response = EncryptionTool.getMD5(value);
		}
	}

	private String concatWithSeparator(String seq,String ...args)
	{
		String value = "";
		for(int i=0;i<args.length;i++)
		{
			value += args[i];
			value += seq;
		}

		if(args.length > 0)
		{
			int len = value.length() - seq.length();
			value = value.substring(0, len);
		}

		return value;
	}

	private String generateCNonce(int length)
	{
		byte[] n = new byte[length];
		new Random().nextBytes(n);
		String value = Base64.encodeToString(n, Base64.DEFAULT);//.encodeToString(n, Base64.DEFAULT);
		if(value != null)
		{
			value = value.trim();
		}

		return value;

//	Random ran = new Random();
//	int a = ran.nextInt(99999999);
//	int b = ran.nextInt(99999999);
//	long l = a * 10000000L + b;
//	return String.valueOf(l);
	}

	public String getDscpStr()
	{
		StringBuffer strBuf = new StringBuffer(authType);
		strBuf.append(" ");
		strBuf.append("username=\"").append(username).append("\",");
		strBuf.append("realm=\"").append(realm).append("\",");
		strBuf.append("nonce=\"").append(nonce).append("\",");
		strBuf.append("uri=\"").append(uri).append("\",");
		strBuf.append("response=\"").append(response).append("\",");
		strBuf.append("qop=").append(qop).append(",");
		strBuf.append("nc=").append(nc).append(",");
		strBuf.append("opaque=\"").append(opaque).append("\",");
		strBuf.append("cnonce=\"").append(cnonce).append("\"");

		// strBuf.append("username=\"").append(username).append("\"");

		return strBuf.toString();
	}

	private void parse(String authStr)
	{
		if(authStr == null
				|| authStr.length() <= 0)
		{
			return;
		}
		authStr = authStr.trim();

		int index = authStr.indexOf(' ');
		if(index != -1)
		{
			this.authType = authStr.substring(0, index);
			authStr = authStr.substring(index + 1, authStr.length());
		}

		String[] strArr = authStr.split(",");
		valueMap = new HashMap<String, String>();
		for (int i = 0; i < strArr.length; i++)
		{
			String value = strArr[i];
			String[] valueArr = value.split("=");
			if (valueArr.length == 2)
			{
				if (valueArr[0] != null && valueArr[1] != null)
				{
					String valueStr = valueArr[1].trim();
					valueStr = getStringStr(valueStr);
					valueMap.put(valueArr[0].trim(), valueStr);
				}
			}
		}
	}

	private String getValue(String key)
	{
		if (key == null || key.equals(""))
		{
			return DefauleValue;
		}
		if (valueMap == null || valueMap.size() <= 0)
		{
			return DefauleValue;
		}

		String value = valueMap.get(key);
		if (value != null)
		{
			return value;
		}

		return DefauleValue;
	}

	private String getStringStr(String str)
	{
		if (str.startsWith("\""))
		{
			// 字符串以"开头，去掉"
			str = str.substring(1, str.length() - 1);
		}
		if (str.endsWith("\""))
		{
			// 字符串以"结尾，去掉"
			str = str.substring(0, str.length() - 2);
		}
		return str;
	}

	public String getAuthType()
	{
		return authType;
	}
}
